use std::any::{Any, TypeId};
use std::collections::HashMap;
use log::info;

trait MyTrait {
    fn do_something(&self);
}

struct TraitRegistry {
    implementations: HashMap<TypeId, fn(&dyn Any) -> Option<&dyn MyTrait>>,
}

impl TraitRegistry {
    fn new() -> Self {
        Self {
            implementations: HashMap::new(),
        }
    }

    fn register<T: MyTrait + Any>(&mut self) {
        self.implementations.insert(
            TypeId::of::<T>(),
            |any| any.downcast_ref::<T>().map(|t| t as &dyn MyTrait)
        );
    }

    fn get_my_trait<'a>(&self, any: &'a dyn Any) -> Option<&'a dyn MyTrait> {
        let type_id = any.type_id();
        if let Some(&converter) = self.implementations.get(&type_id) {
            converter(any)
        } else {
            None
        }
    }
}

struct MyStruct;
impl MyTrait for MyStruct {
    fn do_something(&self) {
        info!("MyStruct doing something");
    }
}

struct OtherStruct;

#[test]
fn main() {
    let mut registry = TraitRegistry::new();
    registry.register::<MyStruct>();

    let my_struct = MyStruct;
    let other_struct = OtherStruct;

    let any1: &dyn Any = &my_struct;
    let any2: &dyn Any = &other_struct;

    if let Some(my_trait) = registry.get_my_trait(any1) {
        my_trait.do_something(); // 会执行
    }

    if let Some(my_trait) = registry.get_my_trait(any2) {
        my_trait.do_something(); // 不会执行
    } else {
        info!("other_struct 没有实现 MyTrait");
    }
}


// 自定义 trait，继承自 Any，并提供一个方法检查是否实现了 MyTrait
trait MyAny: Any {
    fn as_my_trait(&self) -> Option<&dyn MyTrait>;
}

// 为所有实现了 MyTrait 和 Any 的类型实现 MyAny
impl<T: MyTrait + Any> MyAny for T {
    fn as_my_trait(&self) -> Option<&dyn MyTrait> {
        Some(self)
    }
}

impl MyTrait for String {
    fn do_something(&self) {
        info!("MyStruct doing something");
    }
}

#[test]
fn any_test() {
    let str = "dddd".to_string();
    if let Some(t) = str.as_my_trait() {
        t.do_something();
    }
}


